package org.framework.lazy.cloud.network.heartbeat.server.netty.permeate.tcp.handler;


import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelOption;
import io.netty.channel.SimpleChannelInboundHandler;
import lombok.extern.slf4j.Slf4j;
import org.framework.lazy.cloud.network.heartbeat.common.NettyByteBuf;
import org.framework.lazy.cloud.network.heartbeat.common.adapter.ChannelFlowAdapter;
import org.framework.lazy.cloud.network.heartbeat.common.advanced.payload.NettyProxyMsg;
import org.framework.lazy.cloud.network.heartbeat.common.constant.TcpMessageType;
import org.framework.lazy.cloud.network.heartbeat.common.enums.ChannelFlowEnum;
import org.framework.lazy.cloud.network.heartbeat.common.utils.ChannelAttributeKeyUtils;
import org.framework.lazy.cloud.network.heartbeat.server.netty.flow.permeate.ServerPermeateChannelFlow;
import org.wu.framework.spring.utils.SpringContextHolder;

/**
 * 客户端渗透服务端
 */
@Slf4j
public class NettyTcpClientPermeateServerRealHandler extends SimpleChannelInboundHandler<NettyByteBuf> {


    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        // 根据访客ID 确认真实通道 读写打开
        Channel channel = ctx.channel();
        Channel nextChannel = ChannelAttributeKeyUtils.getNextChannel(channel);

        channel.config().setOption(ChannelOption.AUTO_READ, true);
        super.channelActive(ctx);
    }


    @Override
    public void channelRead0(ChannelHandlerContext ctx, NettyByteBuf nettyByteBuf) {

        Channel channel = ctx.channel();
        byte[] bytes = nettyByteBuf.getData();
        log.debug("bytes.length:{}", bytes.length);
        log.debug("【客户端渗透服务端】服务端真实服务数据:{}", new String(bytes));
        Channel nextChannel = ChannelAttributeKeyUtils.getNextChannel(channel);
        // 消息下发到客户端
        String clientId = ChannelAttributeKeyUtils.getClientId(channel);
        Integer visitorPort = ChannelAttributeKeyUtils.getVisitorPort(channel);

        if (nextChannel != null) {
            NettyProxyMsg nettyMsg = new NettyProxyMsg();
            nettyMsg.setType(TcpMessageType.TCP_DISTRIBUTE_CLIENT_PERMEATE_SERVER_TRANSFER);
            nettyMsg.setData(bytes);

            nextChannel.writeAndFlush(nettyMsg);
            ChannelFlowAdapter channelFlowAdapter = SpringContextHolder.getBean(ChannelFlowAdapter.class);
            // 记录出口数据
            ServerPermeateChannelFlow serverPermeateChannelFlow = ServerPermeateChannelFlow
                    .builder()
                    .channelFlowEnum(ChannelFlowEnum.OUT_FLOW)
                    .port(visitorPort)
                    .clientId(clientId)
                    .flow(nettyMsg.getData().length)
                    .build();
            channelFlowAdapter.asyncHandler(channel, serverPermeateChannelFlow);
        } else {
            log.error("we can not find next channel  for transfer  with client permeate server user client_id:{} ", clientId);
        }


    }


    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        //  客户端真实通信通道
        Channel nextChannel = ChannelAttributeKeyUtils.getNextChannel(ctx.channel());
        if (nextChannel != null) {
            log.info("【客户端渗透服务端】服务端真实连接断开");
            // 下发关闭这个客户端的访客通道
            NettyProxyMsg closeVisitorMsg = new NettyProxyMsg();
            closeVisitorMsg.setType(TcpMessageType.TCP_DISTRIBUTE_CLIENT_PERMEATE_SERVER_TRANSFER_CLOSE);
            nextChannel.writeAndFlush(closeVisitorMsg);
        }

        super.channelInactive(ctx);
    }

    @Override
    public void channelWritabilityChanged(ChannelHandlerContext ctx) throws Exception {
        log.info("channelWritabilityChanged");

    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        log.info("exceptionCaught:{}", cause.getMessage());
        super.exceptionCaught(ctx, cause);
    }
}